package com.wg.springboot.stream;


import com.google.common.collect.Lists;
import com.wg.springboot.stream.Employee;
import org.junit.Test;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

//jdk8  流的创建  中间操作  终止操作
public class SteamDemo {
    void steamDemo() {
        ArrayList<String> arraylist = new ArrayList<>();
        arraylist.add("1");
        arraylist.add("2");
        //创建流  是collection的默认方法
        Stream<String> stream = arraylist.stream();
        //并行流
        Stream<String> stream1 = arraylist.parallelStream();
        stream.forEach(s -> System.out.println());
        stream.forEach(System.out::println);
        //第二种方式  Arrays工具
        String[] arr = {"1"};
        Stream<String> stream2 = Arrays.stream(arr);
        stream2.forEach(System.out::println);
        //第三种方式 通过Stream接口方法
        Stream<Integer> stream3 = Stream.of(1, 2, 3);
        //迭代流
        Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
        stream4.limit(10).forEach(System.out::println);//中间操作  限制10个
        //生成流
        Stream<Integer> stream5 = Stream.generate(() -> new Random().nextInt(100));
        stream5.limit(10).forEach(System.out::println);
        //第四种方式
        IntStream stream6 = IntStream.of(1, 2, 3);
        IntStream stream7 = IntStream.range(0, 50);//生成0-49之间的数
        IntStream stream8 = IntStream.rangeClosed(0, 50);//生成0-50之间的数
        //额外还有LongStream  DoubleStream
//流的中间操作
        ArrayList<Employee> list = new ArrayList<>();
        list.add(new Employee("a", 10000));
        list.add(new Employee("b", 20000));
        //创建流
        list.stream()
                .filter(s -> s.getMoney() > 100) //过滤工资大于100
                .forEach(System.out::println);
        list.stream()
                .skip(1)//跳过几个元素
                .forEach(System.out::println);
        list.stream()
                .distinct()//去除重复的  但是得前提重写hashcode和eques
                .forEach(System.out::println);
        list.stream()
                .sorted((e1, e2) -> Double.compare(e1.getMoney(), e2.getMoney()))  //按工资从小到大
                .forEach(System.out::println);
        //中间操作2  map把一组数据映射成另一组数据
        list.stream()
                .map(e -> e.getName()) //映射成一组只有名字的
                .forEach(System.out::println);
        //中间操作3  并行流  多线程
        list.parallelStream()
                .forEach(System.out::println);
        //终止操作  forEach也是
        Optional<Employee> min = list.stream() //返回该对象是防止空指针
                .min((e1, e2) -> Double.compare(e1.getMoney(), e2.getMoney()));
        System.out.println(min.get());//输出最小值
        list.stream()
                .max((o1, o2) -> Double.compare(o1.getMoney(), o2.getMoney()));
        long count = list.stream().count();//统计计数
        //计算工资和
        Optional<Double> reduce = list.stream()
                .map(e -> e.getMoney()) //先把工资映射出来
                .reduce((a, b) -> a + b);//规约
        System.out.println(reduce.get());
        //收集并封装
        List<String> collect = list.stream()
                .map(e -> e.getName())
                .collect(Collectors.toList());//stream提供的  把收集好的放到list集合
//        2021年11月8日16:35:45   jdk11
        String[] strings = {};
        List<String> realAdd = Arrays.asList(strings);
        String str = "1";
        List<String> strings1 = Arrays.asList(str);
        Integer integer = 1;
        List<Integer> integers = Arrays.asList(integer);
        LocalDate of = LocalDate.of(2019, 1, 21);
        Set<Integer> integers1 = Set.of(1, 2);
        Stream.of();
//        允许为空
        Stream.ofNullable(null);

    }

    @Test
    public void say() {
        Stream<Integer> integerStream = Stream.of(2, 2, 4, 3);
//        第一个/2==1就放到收集里面继续往下走  第一个都不满足就直接终止
        List<Integer> collect1 = integerStream.takeWhile(Number -> Number / 2 == 1).collect(Collectors.toList());
        for (Integer i : collect1) {
            System.out.println(i.intValue());//2  2
        }
        Stream<Integer> integerStream2 = Stream.of(2, 2, 4, 3, 2);
//        把满足条件的丢弃  当有满足条件的之后就失效了后面的全部都展现的  第一个就不满足就全部输出
        List<Integer> collect = integerStream2.dropWhile(Number -> Number / 2 == 1).collect(Collectors.toList());
        for (Integer i : collect) {
            System.out.println(i.intValue());//4 3 2
        }
    }

    public static void main(String[] args) {
//        根据起始值seed(0)，每次生成一个指定递增值（n+1）的数，limit(5)用于截断流的长度，即只获取前5个元素。
        Stream.iterate(0, n -> n + 1).limit(5).forEach(a -> {
            System.out.println(a);
        });
    }

    @Test
    public void say2() throws IOException {
        String i = " 1 ";
//        是否为空
        System.out.println(i.isBlank());
//        去掉前后空白
        System.out.println(i.strip());
//        去掉前面空白
        System.out.println(i.stripLeading());
//        去除尾部空白
        System.out.println(i.stripTrailing());
        System.out.println("*******************************************");

        List<String> list = null;
//        判空处理
        String list2 = null;
        String s = Optional.ofNullable(list2).orElse("9");
        System.out.println(s);
        Exception exception = new Exception();
//        改变异常类型
//        String s1 = Optional.ofNullable(list2).orElseThrow(()->new RuntimeException());
//        System.out.println(s1);

        List<String> list3 = new ArrayList<>();
        list3.add("1");
        list3.add("1");
        list3.add("2");
        List<String> newList3 = Optional.ofNullable(list3).orElse(Lists.newArrayList());
        newList3.forEach(x -> System.out.println(x));
//复制2   两次
        System.out.println("a".repeat(2)); //aa

//每个都换一行的意思  当我们要从文件中读取内容并分别处理每个字符串时  下面不能展示效果
        String str = "\n A \n B \n C \n D";
        Stream<String> lines = str.lines();
        lines.forEach(System.out::println);
        System.out.println(str);

    }

    @Test
    public void uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
//        传入一个文件 转发到另一个地方（或者说复制一份到另一个地方）  jdk11
        String path = "D:/filesss/" + "";
        File newFile = new File(path);
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候）
        file.transferTo(newFile);
    }

}
